package cate.game.pvp.championrace.data;

import cate.common.table.d.GDChampionRace;
import cate.game.db.mongo.kv.KvMongo;
import cate.game.event.championrace.ChampionRaceTimerEvent;
import cate.game.framework.advanced.AdvancedLongAttributes;
import easy.java.dev.note.NoteField;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;


import static cate.game.pvp.championrace.ChampionRaceSpecUtils.*;
import static cate.game.event.championrace.ChampionRaceTimerEvent.EventType.*;


@Data
@Slf4j
public class GameChampionRaceKV extends KvMongo {
    private int season;
    private long openTime;
    private long closeTime;

    @NoteField(value = "阶段信息")
    private ChampionRaceSpec spec;

    @NoteField(value = "当前处于什么事件阶段")
    private AdvancedLongAttributes eventAttributes;

    @Override
    public String getKeyPrefix() {
        return KvMongo.KEY_CHAMPION_RACE;
    }

    @Override
    public void initialize() {
        if (spec == null) {
            spec = new ChampionRaceSpec();
        }
        if (eventAttributes == null) {
            eventAttributes = AdvancedLongAttributes.of(0L);
        }
    }

    public void updateToNew(ChampionRaceSpec spec, long openTime, long closeTime, AdvancedLongAttributes attributes, boolean updateAttributes) {
        if (updateAttributes) {
            setEventAttributes(attributes);
        }
        setSpec(spec);
        setSeason(spec.getSeason());
        setOpenTime(openTime);
        setCloseTime(closeTime);
        log.info("同步了跨服最新状态，spec={}, openTime={}, closeTime={}， attributtes={}, updateAttributes={}", spec, openTime, closeTime, attributes, updateAttributes);
    }

    public boolean onOpenEvent(ChampionRaceTimerEvent.OpenEvent openEvent) {
        if (getEventAttributes().hasAttribute(OPEN.getFlag())
                && getSeason() == openEvent.getSeason()) {
            setOpenTime(openEvent.getOpenTime());
            setCloseTime(openEvent.getClosedTime());
            return false;
        }
        log.info("处理了事件:{}", openEvent);
        getEventAttributes().clear();
        setSpec(openEvent.getSpec());
        setSeason(openEvent.getSeason());
        setOpenTime(openEvent.getOpenTime());
        setCloseTime(openEvent.getOpenTime() + GDChampionRace.WHOLE_SEASON_TIME);
        getEventAttributes().setAttribute(OPEN.getFlag());
        return true;
    }

    private void fixOpenEvent(ChampionRaceSpec spec) {
        if (getSeason() < spec.getSeason()) {
            ChampionRaceTimerEvent.OpenEvent openEvent = new ChampionRaceTimerEvent.OpenEvent();
            openEvent.setSpec(spec);
            openEvent.setSeason(spec.getSeason());
            openEvent.setOpenTime(getOpenTime() + GDChampionRace.WHOLE_SEASON_TIME);
            openEvent.setClosedTime(getCloseTime() + GDChampionRace.WHOLE_SEASON_TIME);
            log.info("开始修正open事件，openEvent={}", openEvent);
            onOpenEvent(openEvent);
        }
    }

    public boolean onRankSettleEvent(ChampionRaceTimerEvent.RankSettleEvent rankSettleEvent) {
        fixOpenEvent(rankSettleEvent.getSpec());
        if (getEventAttributes().hasAttribute(RANK_SETTLE.getFlag())) {
            return false;
        }
        log.info("处理了事件:{}", rankSettleEvent);
        this.setSpec(rankSettleEvent.getSpec());
        getEventAttributes().setAttribute(RANK_SETTLE.getFlag());
        return true;
    }

    public boolean onInvitationEvent(ChampionRaceTimerEvent.InvitationEvent invitationEvent) {
        fixOpenEvent(invitationEvent.getSpec());
        if (getEventAttributes().hasAttribute(INVITATION.getFlag())) {
            return false;
        }
        log.info("处理了事件:{}", invitationEvent);
        this.setSpec(invitationEvent.getSpec());
        getEventAttributes().setAttribute(INVITATION.getFlag());
        return true;
    }

    public boolean onTrialEvent(ChampionRaceTimerEvent.TrialEvent trialEvent) {
        if (getEventAttributes().hasAttribute(getTrialFlag(trialEvent))) {
            return false;
        }
        log.info("处理了事件:{}", trialEvent);
        this.setSpec(trialEvent.getSpec());
        getEventAttributes().setAttribute(getTrialFlag(trialEvent));
        return true;
    }

    public boolean onKoEvent(ChampionRaceTimerEvent.KoEvent koEvent) {
        if (getEventAttributes().hasAttribute(getKoFlag(koEvent))) {
            return false;
        }
        log.info("处理了事件:{}", koEvent);
        this.setSpec(koEvent.getSpec());
        getEventAttributes().setAttribute(getKoFlag(koEvent));
        return true;
    }

    public boolean onFinalEvent(ChampionRaceTimerEvent.FinalEvent finalEvent) {
        if (getEventAttributes().hasAttribute(getFinalFlag(finalEvent))) {
            return false;
        }
        log.info("处理了事件:{}", finalEvent);
        this.setSpec(finalEvent.getSpec());
        getEventAttributes().setAttribute(getFinalFlag(finalEvent));
        return true;
    }

    public boolean onRankSwitchEvent(ChampionRaceTimerEvent.RankSwitchEvent rankSwitchEvent) {
        if (getEventAttributes().hasAttribute(RANK_SWITCH.getFlag())) {
            return false;
        }
        log.info("处理了事件:{}", rankSwitchEvent);
        this.setSpec(rankSwitchEvent.getSpec());
        getEventAttributes().setAttribute(RANK_SWITCH.getFlag());
        return true;
    }

    public boolean onShowEvent(ChampionRaceTimerEvent.ShowEvent showEvent) {
        if (getEventAttributes().hasAttribute(SHOW.getFlag())) {
            return false;
        }
        log.info("处理了事件:{}", showEvent);
        this.setSpec(showEvent.getSpec());
        getEventAttributes().setAttribute(SHOW.getFlag());
        return true;
    }

    public boolean onRestEvent(ChampionRaceTimerEvent.RestEvent restEvent) {
        if (getEventAttributes().hasAttribute(REST.getFlag())) {
            return false;
        }
        log.info("处理了事件:{}", restEvent);
        this.setSpec(restEvent.getSpec());
        getEventAttributes().setAttribute(REST.getFlag());
        return true;
    }
}
